import { InjectRepository } from '@nestjs/typeorm';
import { ShopUsersEntity } from './entities/shop-users.entity';
import { Repository } from 'typeorm';
import { CreateShopUserDto, ListShopUsersDto, LoginDto, UpdateShopUsersDto } from './dto/shop-users.dto';
import { ResultData } from 'src/common/utils/result';
import * as bcrypt from 'bcryptjs';
import { BadRequestException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { GenerateUUID } from 'src/common/utils';
import { UserType } from 'src/module/system/user/dto/user';
import { RedisService } from 'src/module/common/redis/redis.service';
import { CacheEnum } from 'src/common/enum';
import { LOGIN_TOKEN_EXPIRESIN } from 'src/common/constant';

export class ShopUsersService {
  constructor(
    @InjectRepository(ShopUsersEntity)
    private readonly shopUsersRepo: Repository<ShopUsersEntity>,
    private jwtService: JwtService,
    private redisService: RedisService,
  ) {}

  async create(shopUser: CreateShopUserDto) {
    const salt = bcrypt.genSaltSync(10);
    if (shopUser.password) {
      shopUser.password = await bcrypt.hashSync(shopUser.password, salt);
    }
    return await this.shopUsersRepo.save(shopUser);
  }

  async appLogin(data: LoginDto) {
    const user = await this.shopUsersRepo.findOne({
      where: {
        username: data.username,
      },
    });
    if (!(user && bcrypt.compareSync(data.password, user.password))) {
      return ResultData.fail(500, '账号或密码错误');
    }
    const uuid = GenerateUUID();
    const token = this.createToken({ uuid, userId: user.id });
    await this.updateRedisToken(uuid, user);
    return ResultData.ok({ token }, '登录成功');
  }

  createToken(payload: { uuid: string; userId: number }) {
    const accessToken = this.jwtService.sign(payload);
    return accessToken;
  }
  /**
   * 更新redis中的元数据
   * @param token
   * @param metaData
   */
  async updateRedisToken(token: string, metaData: Record<string, any>) {
    const oldMetaData = await this.redisService.get(`${CacheEnum.LOGIN_TOKEN_KEY}${token}`);

    let newMetaData = metaData;
    if (oldMetaData) {
      newMetaData = Object.assign(oldMetaData, metaData);
    }

    await this.redisService.set(`${CacheEnum.LOGIN_TOKEN_KEY}${token}`, newMetaData, LOGIN_TOKEN_EXPIRESIN);
  }

  async findAll(query: ListShopUsersDto) {
    const entity = this.shopUsersRepo.createQueryBuilder('shopUser');
    if (query.username) {
      entity.andWhere(`shopUser.username LIKE "%${query.username}%"`);
    }

    if (query.pageSize && query.pageNum) {
      entity.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }
    const [list, total] = await entity.getManyAndCount();
    return ResultData.ok({
      list,
      total,
    });
  }

  async findOne(id: number) {
    const found = await this.shopUsersRepo.findOneBy({ id });
    return ResultData.ok(found);
  }

  async update(data: UpdateShopUsersDto) {
    const { id, ...rest } = data;
    if (!id) {
      throw new BadRequestException('id不得为空');
    }
    const foundData = await this.findOne(id);
    if (!foundData.data) {
      throw new BadRequestException(`未找到id为${id}的这条数据`);
    }
    this.shopUsersRepo.update(id, rest);
    return ResultData.ok();
  }

  async remove(id: number) {
    return this.shopUsersRepo.delete(id);
  }
}
